// import WebSocket from "ws";
import * as WebSocket from "ws";
import { load } from "protobufjs"; 

load("rtsp.proto", function (err, root) {
    if (err)
        throw err;
});
//------------------------- config -------------------------
const HEARTBEAT_INTERVAL = 10000;//30000;// 30s
const HEARTBEAT_TIMEOUT = HEARTBEAT_INTERVAL + 10000;// +10s
const WEBSOCEKT_PORT = 9090;
//------------------------- config -------------------------


//------------------------- https + ws -------------------------
// import { createServer as createHttpsServer } from "https";
// import { readFileSync } from "fs";
// const server = createHttpsServer({
//     cert: readFileSync('/path/to/cert.pem'),
//     key: readFileSync('/path/to/key.pem')
// });
// const server = new WebSocketServer({ server });

//------------------------- http + ws -------------------------
// import { createServer as createHttpServer } from "http";
// const server = createHttpServer();
// const server = new WebSocketServer({ server });

//-------------------------  ws -------------------------
const server = new WebSocket.Server({ port: WEBSOCEKT_PORT });

server.on('close', function close(): void{
    console.log('>>>[server.close]<<<');
});

server.on('connection', function connection(client: any, request:any) {
    let ip: string | undefined = request.connection.remoteAddress;
    const xForwardedFor: any = request.headers['x-forwarded-for'];
    if (xForwardedFor && typeof (xForwardedFor) == "string" && xForwardedFor.length > 0){
        ip = xForwardedFor.split(/\s*,\s*/)[0];
    }
    console.log(">>>[server.connection]<<<");
    console.log(`new websocket client[${ip}]`);
    // console.log(client);
    // console.log(request);
    client.isAlive = true;

    client.on('close', function close(code:number,reason:string) {
        console.log('!!![client.close]!!!');
        console.log(code);
        console.log(reason);
    });
    client.on('error', function error(error:Error) {
        console.log('!!![client.close]!!!');
        console.log(error);
    });
    client.on('message', function message(message: string | Buffer | ArrayBuffer | Buffer[]) {
        console.log('!!![client.message]!!!');
        console.log(message);
        console.log('Send Response Data To Client <<<<<<<<<<<<');
        client.send('Send Response Data To Client <<<<<<<<<<<<');
    });

    client.on('open', function open() {
        console.log('!!![client.open]!!!');
    });

    client.on('ping', function ping(this: any, data: Buffer) {
        console.log('!!![client.ping]!!!');
    });

    client.on('pong', function pong(this: any, data: Buffer) {
        console.log('!!![client.pong]!!!');
        console.log('Send Viedo Data To Client <<<<<<<<<<<<');
        client.send('Send Viedo Data To Client <<<<<<<<<<<<');
        this.isAlive = true;
    });

    client.on('unexpected-response', function unexpected_response(request:any,response:any) {
        console.log('!!![client.unexpected-response]!!!');
        console.log(request);
        console.log(response);
    });

    client.on('upgrade', function upgrade(response:any) {
        console.log('!!![client.upgrade]!!!');
        console.log(response);
    });
});

server.on('close', function close(): void{
    console.log('>>>[server.close]<<<');
});

server.on('headers', function headers(headers:any,request:any):void {
    console.log('>>>[server.headers]<<<');
    // console.log(headers);
    // console.log(request);
});

server.on('listening', function listening(): void {
    console.log(`>>>[server.listening]<<<`);
    console.log(`start listen [${JSON.stringify(server.address())}]`);
});

const interval:NodeJS.Timeout = setInterval(function ping() {
    server.clients.forEach(function each(ws:any) {
        if (ws.isAlive === false) return ws.terminate();
        ws.isAlive = false;
        ws.ping(function noop(){});
    });
}, HEARTBEAT_INTERVAL);

process.on('exit', (code:any) => {
    console.log(`About to exit with code: ${code}`);
    clearInterval(interval);
});

//------------------------- http/s + ws -------------------------
// server.listen(wsPort, () => {
//     console.log("listen port: " + httpPort);
// });
//------------------------- http / s + ws-------------------------